//
// Created by mio on 25-4-11.
//

#include "EventLoop.h"
#include "SelectTaskScheduler.h"
#include <iostream>

EventLoop::EventLoop(uint32_t num_threads) : index_(1), num_threads_(num_threads == 0 ? 1 : num_threads)
{
    this->Loop();
}

EventLoop::~EventLoop()
{
    this->Quit();
}

TaskSchedulerPtr EventLoop::GetTaskScheduler()
{
    // 如果只有一个 TaskScheduler (单线程模式)
    if (task_schedulers_.size() == 1)
        return task_schedulers_.at(0);
    else
    {
        auto task_scheduler = task_schedulers_.at(index_);
        index_ = (index_ + 1) % task_schedulers_.size();
        return task_scheduler;
    }
    return nullptr;
}

TimerId EventLoop::AddTimer(const TimerEvent& event, uint32_t mesc)
{
    if (task_schedulers_.size() > 0)
    {
        return task_schedulers_[0]->AddTimer(event, mesc);
    }
    return 0;
}

void EventLoop::RemoveTimer(TimerId timerId)
{
    if (task_schedulers_.size() > 0)
    {
        task_schedulers_[0]->RemoveTimer(timerId);
    }
}

void EventLoop::UpdateChannel(ChannelPtr channel)
{
    if (task_schedulers_.size() > 0)
    {
        task_schedulers_[0]->UpdateChannel(channel);
    }
}

void EventLoop::RemoveChannel(ChannelPtr channel)
{
    if (task_schedulers_.size() > 0)
    {
        task_schedulers_[0]->RemoveChannel(channel);
    }
}

void EventLoop::Loop()
{
    // 防止重复初始化
    if (!task_schedulers_.empty()) return;

    // 根据 num_threads_ 创建相应数量的 TaskScheduler 和线程
    for (uint32_t n = 0; n < num_threads_; n++)
    {
        std::shared_ptr<TaskScheduler> task_scheduler_ptr(new SelectTaskScheduler(n));
        task_schedulers_.push_back(task_scheduler_ptr);

        // 这里传递 shared_ptr 可以保证线程运行时 scheduler 对象仍然有效
        // 但 std::thread 构造函数可能只拷贝指针，需确认其行为
        // 更安全的做法是用 lambda 捕获 shared_ptr:
        // [scheduler = task_scheduler_ptr]() { scheduler->Start(); }
        std::shared_ptr<std::thread> loopthread(new std::thread(&TaskScheduler::Start, task_scheduler_ptr.get()));
        loopthread->native_handle(); // 调用 native_handle() 本身无副作用，通常用于获取底层句柄进行特殊操作，这里似乎不需要。
        threads_.push_back(loopthread);
        std::cout << "create thread id is : " << loopthread->get_id() << "\n";
    }
}

void EventLoop::Quit()
{
    // 1. 请求所有 TaskScheduler 停止它们的事件循环
    for (const auto& scheduler : task_schedulers_)
    {
        if (scheduler) scheduler->Stop();
    }
    for (auto it : threads_)
    {
        if (it->joinable())
            it->join();
    }
    task_schedulers_.clear();
    threads_.clear();
}
